package com.exrobot.module.rbt.service.orderitem;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.exrobot.framework.common.util.collection.CollectionUtils;
import com.exrobot.framework.common.util.date.LocalDateTimeUtils;
import com.exrobot.module.rbt.controller.admin.robotinfo.vo.RobotInfoPageReqVO;
import com.exrobot.module.rbt.dal.dataobject.canteeninfo.CanteenInfoDO;
import com.exrobot.module.rbt.dal.dataobject.canteenmenu.CanteenMenuDO;
import com.exrobot.module.rbt.dal.dataobject.order.OrderDO;
import com.exrobot.module.rbt.dal.dataobject.robotinfo.RobotInfoDO;
import com.exrobot.module.rbt.enums.RbtOrderStatusEnum;
import com.exrobot.module.rbt.service.canteeninfo.CanteenInfoService;
import com.exrobot.module.rbt.service.canteenmenu.CanteenMenuService;
import com.exrobot.module.rbt.service.robotinfo.RobotInfoService;
import jodd.util.StringUtil;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import com.exrobot.module.rbt.controller.admin.orderitem.vo.*;
import com.exrobot.module.rbt.dal.dataobject.orderitem.OrderItemDO;
import com.exrobot.framework.common.pojo.PageResult;
import com.exrobot.framework.common.pojo.PageParam;
import com.exrobot.framework.common.util.object.BeanUtils;

import com.exrobot.module.rbt.dal.mysql.orderitem.OrderItemMapper;
import software.amazon.awssdk.services.s3.endpoints.internal.Value;

import static com.exrobot.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.exrobot.framework.common.util.collection.CollectionUtils.*;
import static com.exrobot.module.rbt.enums.ErrorCodeConstants.*;

/**
 * 订单信息 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class OrderItemServiceImpl implements OrderItemService {

    @Resource
    private RobotInfoService robotInfoService;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private CanteenMenuService canteenMenuService;

    @Resource
    private CanteenInfoService canteenInfoService;

    @Override
    public Long createOrderItem(OrderItemSaveReqVO createReqVO) {
        // 插入
        OrderItemDO orderItem = BeanUtils.toBean(createReqVO, OrderItemDO.class);
        orderItemMapper.insert(orderItem);

        // 返回
        return orderItem.getId();
    }

    @Override
    public void updateOrderItem(OrderItemSaveReqVO updateReqVO) {
        // 校验存在
        validateOrderItemExists(updateReqVO.getId());
        // 更新
        OrderItemDO updateObj = BeanUtils.toBean(updateReqVO, OrderItemDO.class);
        orderItemMapper.updateById(updateObj);
    }

    @Override
    public void deleteOrderItem(Long id) {
        // 校验存在
        validateOrderItemExists(id);
        // 删除
        OrderItemDO orderItemDO = new OrderItemDO();
        orderItemDO.setId(id).setStatus(RbtOrderStatusEnum.EXPIRE.getVal());
        orderItemMapper.updateById(orderItemDO);
    }

    @Override
    public void deleteOrderItemListByIds(List<Long> ids) {
        // 删除
        LambdaUpdateWrapper<OrderItemDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(OrderItemDO::getId,ids)
                .in(OrderItemDO::getStatus,Arrays.asList(RbtOrderStatusEnum.WAIT.getVal(),RbtOrderStatusEnum.ORDER.getVal()));
        orderItemMapper.update(null,updateWrapper);
    }


    private void validateOrderItemExists(Long id) {
        if (orderItemMapper.selectById(id) == null) {
            throw exception(RBT_DATA_NOT_EXISTS);
        }
    }

    @Override
    public OrderItemDO getOrderItem(Long id) {
        return orderItemMapper.selectById(id);
    }

    @Override
    public List<OrderItemDO> getOrderItemList(OrderItemPageReqVO pageReqVO) {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        return orderItemMapper.selectPage(pageReqVO).getList();
    }

    @Override
    public PageResult<OrderItemRespVO> getOrderItemPage(OrderItemPageReqVO pageReqVO) {
        PageResult<OrderItemRespVO> result = new PageResult<>();
        if(StringUtil.isNotBlank(pageReqVO.getRobotName())) {
           List<RobotInfoDO> robotInfoDOList = robotInfoService.getRobotInfoList(new RobotInfoPageReqVO().setName(pageReqVO.getRobotName()));
           if(robotInfoDOList == null || robotInfoDOList.isEmpty()) {
               return result;
           }
           pageReqVO.setRobotSns(robotInfoDOList.stream().map(RobotInfoDO::getSn).collect(Collectors.toSet()));
        }
        PageResult<OrderItemDO> pageResult = orderItemMapper.selectPage(pageReqVO);
        if(pageResult == null || pageResult.getTotal() == 0) {
            result.setTotal(0L);
            return result;
        }
        result.setTotal(pageResult.getTotal());
        List<OrderItemDO> list = pageResult.getList();
        Collection<String> robotSns = list.stream().map(OrderItemDO::getRobotSn).filter(StringUtil::isNotBlank).collect(Collectors.toSet());
        Map<String, RobotInfoDO> robotInfoDOMap = robotInfoService.getRobotInfoMap(robotSns);
        Collection<Long> menuSns = list.stream().map(OrderItemDO::getMenuSn).collect(Collectors.toSet());
        Map<Long, CanteenMenuDO> menuDOMap = canteenMenuService.getCanteenMenuMapByMenuSn(menuSns);
        Collection<Long> canteenSns = list.stream().map(OrderItemDO::getCanteenSn).collect(Collectors.toSet());
        Map<Long, CanteenInfoDO> canteenInfoDOMap = canteenInfoService.getCanteenInfoMap(canteenSns);
        List<OrderItemRespVO> listResp = BeanUtils.toBean(list,OrderItemRespVO.class,obj->{
            if (menuDOMap.containsKey(obj.getMenuSn())) {
                obj.setMenuName(menuDOMap.get(obj.getMenuSn()).getName());
            }
            if(canteenInfoDOMap.containsKey(obj.getCanteenSn())) {
                obj.setCanteenName(canteenInfoDOMap.get(obj.getCanteenSn()).getName());
            }
            if (robotInfoDOMap.containsKey(obj.getRobotSn())) {
                obj.setRobotName(robotInfoDOMap.get(obj.getRobotSn()).getName());
            }
        });
        result.setList(listResp);
        return result;
    }


    @Override
    public Map<String,List<Integer>> getAllRobotUseBox() {
        OrderItemPageReqVO reqVO = new OrderItemPageReqVO();
        reqVO.setStatusList(Arrays.asList(RbtOrderStatusEnum.SALE.getVal(),RbtOrderStatusEnum.ORDER.getVal(),RbtOrderStatusEnum.FAIL.getVal()));
        reqVO.setCreateTime(LocalDateTimeUtils.getTodayRange());
        List<OrderItemDO> orderItemDOList = getOrderItemList(reqVO).stream().filter(w->w.getRobotBoxSn() != null).toList();
        return CollectionUtils.convertMultiMap(orderItemDOList,OrderItemDO::getRobotSn,OrderItemDO::getRobotBoxSn);
    }

    @Override
    public Map<String,List<Integer>> getRobotUseBox(Collection<String> robotSns) {
        OrderItemPageReqVO reqVO = new OrderItemPageReqVO();
        reqVO.setRobotSns(robotSns);
        reqVO.setStatusList(Arrays.asList(RbtOrderStatusEnum.SALE.getVal(),RbtOrderStatusEnum.ORDER.getVal(),RbtOrderStatusEnum.FAIL.getVal()));
        reqVO.setCreateTime(LocalDateTimeUtils.getTodayRange());
        List<OrderItemDO> orderItemDOList = getOrderItemList(reqVO).stream().filter(w->w.getRobotBoxSn() != null).toList();
        return CollectionUtils.convertMultiMap(orderItemDOList,OrderItemDO::getRobotSn,OrderItemDO::getRobotBoxSn);
    }


}